﻿using System.IO;
using NLite.Internal;
using NLite.Collections;

namespace NLite
{
    /// <summary>
    /// 属性管理器接口
    /// </summary>
    public interface IPropertyManager
    {
        /// <summary>
        /// 得到属性集
        /// </summary>
        IPropertySet Properties { get; }

        /// <summary>
        /// 加载属性集
        /// </summary>
        void Load();

        /// <summary>
        /// 保存属性集
        /// </summary>
        void Save();
    }

    /// <summary>
    /// 
    /// </summary>
    public class PropertyManager:IPropertyManager
    {
        /// <summary>
        /// 
        /// </summary>
        public IPropertySet Properties { get; private set; }

        private PropertySetOriginator Originator;
        private PropertySetCaretaker Caretaker;
        private static readonly object locker = new object();

        protected PropertyManager() { }

        const string propertyXmlRootNodeName = "Properties";

        /// <summary>
        /// 
        /// </summary>
        public void Init()
        {
           Init(NLiteEnvironment.PropertiesFile);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="propFile"></param>
        public void Init(string propFile)
        {
            Properties = new PropertySet();
            Originator = new PropertySetOriginator(Properties);
            Caretaker = new PropertySetCaretaker();

            Caretaker.FileName = propFile;

            try
            {
                if (!File.Exists(Caretaker.FileName))
                    Caretaker.Save(Originator.CreateMemento());
            }
            catch
            {
            }
        }

        private static PropertyManager instance;

        /// <summary>
        /// 
        /// </summary>
        public static IPropertyManager Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (locker)
                    {
                        if (instance == null)
                        {
                            instance = new PropertyManager();
                            instance.Init();
                            instance.Load();
                        }
                    }
                }

                return instance;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        public static IPropertySet Items
        {
            get { return Instance.Properties; }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="property"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T Get<T>(string property, T defaultValue)
        {
            return Instance.Properties.Get<T>(property, defaultValue);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="property"></param>
        /// <returns></returns>
        public static T Get<T>(string property)
        {
            return Instance.Properties.Get<T>(property);
        }

        /// <summary>
        /// 
        /// </summary>
        public void Load()
        {
            Originator.RestoreMemento(Caretaker.Get());
        }

        /// <summary>
        /// 
        /// </summary>
        public void Save()
        {
            Caretaker.Save(Originator.CreateMemento());
        }
    }
}
